#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<string>
#include<vector>
using namespace std;

//多线程的创建
const int N = 4;

//int* ptr = nullptr; //用于访问独立栈结构

//int g_val = 0; //公有全局变量
__thread int g_val = 0; //私有全局变量

class ThreadData //为了扩展性
{
public:
    ThreadData(const string& name = "")
    :_name(name)
    {}
public:
    string _name;
};

// string tohex(pthread_t tid) //转换为十六进制
// {
//     char buf[32];
//     snprintf(buf, sizeof(buf), "%p", tid);
//     return buf;
// }

void* ThreadRun(void* args) //多个线程均调用一个方法
{
    ThreadData *p = static_cast<ThreadData*>(args); //转换指针
    //int local_val = 10;
    //if(p->_name == "thread-2") ptr = &local_val;
    
    int i = 0;
    while(i < 10)
    {
        //printf("name: %s, pid: %d\n", p->_name.c_str(), getpid());
        //printf("name: %s, tid: %ld, local_val: %d, &local_val: %p\n", p->_name.c_str(), pthread_self(), local_val, &local_val);
        printf("name: %s, tid: %ld, g_val: %d, &g_val: %p\n",p->_name.c_str(), pthread_self(), g_val, &g_val);
        sleep(1);
        //++local_val;
        ++i, ++g_val;
    }
    delete p; //调用析构
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    vector<ThreadData*> ptids;
    for(int i = 1; i <= N; ++i) //创建多线程
    {
        ThreadData* ptid = new ThreadData("thread-" + to_string(i)); //在堆区创建多进程
        pthread_t tid;

        pthread_create(&tid, nullptr, ThreadRun, ptid);
        
        tids.push_back(tid);
        ptids.push_back(ptid);
    }

    sleep(1);
    //进行获取
    //printf("main thread get a local_val: %d, &local_val: %p\n", *ptr, ptr); //打印验证


    //for(auto tid : tids) //等待
    //    pthread_join(tid, nullptr);

    //线程分离
    for(auto tid : tids)
        pthread_detach(tid);
    
    //再进行线程等待
    for(int i = 0; i < N; ++i)
    {
        int n = pthread_join(tids[i], nullptr);
        cout << "retval: " << n << " name: "<< ptids[i]->_name << endl;
    }

    return 0;
}



// //得到tid

// string tohex(pthread_t tid) //转换为十六进制
// {
//     char buf[32];
//     snprintf(buf, sizeof(buf), "%p", tid);
//     return buf;
// }

// void* func(void *args)
// {
//     while(true)
//     {
//         cout << (const char*)args << " id: " << tohex(pthread_self()) << endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, func, (void*)("new thread"));

//     cout << "main thread create a thread, tid: " << tohex(tid) << endl;
    
//     pthread_join(tid, nullptr);
//     return 0;
// }


// int g_val = 0; //验证全局变量是线程之间共享的！

// void show(const string& name) //单个函数可以被多个执行流调用哦给
// {
//     cout << name << " say# " << "welcome" << endl;
// }

// void* threadfunc(void* args) 
// {
//     int cnt = 5;
//     while(cnt--)
//     {
//         //cout << "a new thread, pid: " << getpid() << endl;
//         //show("[new thread]");
//         //int a = 10;
//         //a /= 0; //验证线程崩溃，整个进程崩溃
        
//         g_val++;
//         printf("[new thread]# pid: %d, g_val:%d, &g_val:%p\n", getpid(), g_val, &g_val);
//         sleep(1);
//     }
//     return nullptr; //返回
// }


// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadfunc, nullptr);
//     int cnt = 3;
//     while(cnt--)
//     {
//         //cout << "main thread, pid: " << getpid() << endl;
//         //show("[main thread]");
//         g_val++;
//         printf("[main thread]# pid: %d, g_val:%d, &g_val:%p\n", getpid(), g_val, &g_val);
//         sleep(1);
//     }
//     void *out;
//     pthread_join(tid, &out); //main thread的默认等待方式是阻塞等待！
//     return 0;
// }

